package com.zjk.storage.config;


import cn.hutool.core.util.StrUtil;
import com.zjk.storage.core.FileStorageFactory;
import com.zjk.storage.core.FileStorageService;
import com.zjk.storage.core.aspect.FileStorageAspect;
import com.zjk.storage.core.provider.FileStorage;
import com.zjk.storage.core.provider.amazonS3.AmazonS3Storage;
import com.zjk.storage.core.provider.local.LocalConfig;
import com.zjk.storage.core.provider.local.LocalFileStorage;
import lombok.AllArgsConstructor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.io.File;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

@Configuration
@AllArgsConstructor
@Import(FileStorageProperties.class)
public class StorageAutoConfiguration implements WebMvcConfigurer {

    private final ApplicationContext applicationContext;
    private final FileStorageProperties properties;

    @EventListener(ContextRefreshedEvent.class)
    public void onContextRefreshedEvent() {
        FileStorageService template = applicationContext.getBean(FileStorageService.class);
        template.setSelf(template);
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        LocalConfig localConfig = properties.getLocal();
        if (localConfig.isEnableAccess()) {
            registry.addResourceHandler(localConfig.getPathPatterns())
                    .addResourceLocations("file:" + StrUtil.addSuffixIfNot(localConfig.getBasePath(), File.separator));
        }
    }

    @Bean
    public LocalFileStorage localFileStorage() {
        if (properties.getLocal().getEnable()) {
            return new LocalFileStorage(properties.getLocal());
        }
        return null;
    }

    @Bean
    public AmazonS3Storage amazonS3Storage() {
        if (properties.getAmazonS3().getEnable()) {
            return new AmazonS3Storage(properties.getAmazonS3());
        }
        return null;
    }

    @Bean
    public FileStorageFactory fileStorageFactory(List<? extends FileStorage> fileStorages) {
        FileStorageFactory factory = new FileStorageFactory();
        for (FileStorage fileStorage : fileStorages) {
            factory.addFileStorage(fileStorage.getPlatform(), fileStorage);
        }
        return factory;
    }

    @Bean
    public FileStorageService fileStorageService(FileStorageFactory fileStorageFactory, List<FileStorageAspect> aspects) {
        FileStorageService fileStorageService = new FileStorageService(fileStorageFactory, aspects);
        fileStorageService.setAspects(new CopyOnWriteArrayList<>(aspects));
        return fileStorageService;
    }
}
